package io.filecopy;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyTask implements FileSystemTask {

  private LastModifyTimeMode lastModifyTimeMode;

  private File destFile;

  private File srcFile;

  public CopyTask(File srcFile, File destFile,
      LastModifyTimeMode lastModifyTimeMode) {
    this.srcFile = srcFile;
    this.destFile = destFile;
    this.lastModifyTimeMode = lastModifyTimeMode;
  }

  @Override
  public void execute(ProgressLogger progress) throws IOException {
    long srcTime = srcFile.lastModified();
    boolean replaced = false;
    if (destFile.exists()) {
      replaced = true;
      destFile.createNewFile();
    }

    // TODO kopieren nach NIO
    long size = srcFile.length();
    try {
      FileInputStream fin = new FileInputStream(srcFile);
      FileOutputStream fout = new FileOutputStream(destFile, false);
      byte[] buffer = new byte[4096];
      int bytesRead = 0;
      while ((bytesRead = fin.read(buffer)) != -1) {
        fout.write(buffer, 0, bytesRead);
      }
      fin.close();
      fout.close();
      if (replaced){
        progress.replaceSucceded(size);
      } else {
        progress.copySucceded(size);
      }
    } catch (IOException ioe) {
      if (replaced){
        progress.replaceFailed(size);
      } else {
        progress.copyFailed(size);
      }
      throw ioe;
    }

    switch (lastModifyTimeMode) {
    case KEEP_OR_CURRENT_TIME:
      // keep current time
      break;
    case KEEP_OR_SOURCE_TIME:
      if (replaced) {
        boolean success = destFile.setLastModified(srcTime);
        if (!success){
          progress.modificationTimeChangeFailed();
          System.out.println("modification time change failed: " + destFile.getAbsolutePath());
        }
      }
      break;
    case OVERWRITE_CURRENT_TIME:
      boolean success = destFile.setLastModified(System.currentTimeMillis());
      if (!success){
        progress.modificationTimeChangeFailed();
        System.out.println("modification time change failed: " + destFile.getAbsolutePath());
      }
      break;
    case OVERWRITE_SOURCE_TIME:
      success = destFile.setLastModified(srcTime);
      if (!success){
        progress.modificationTimeChangeFailed();
        System.out.println("modification time change failed: " + destFile.getAbsolutePath());
      }
      break;
    default:
      throw new IllegalStateException("LastModifiedTimeMode "
          + lastModifyTimeMode + " has nnot been implemented yet.");
    }
  }

  @Override
  public String toString() {
    return "copy " + srcFile.getAbsolutePath() + " --> "
        + destFile.getAbsolutePath();
  }
}